package org.paboo.Util;

import java.awt.image.BufferedImage;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.encoder.ByteMatrix;

public class ZxingImage {

	private static Logger log = LogManager.getLogger(ZxingImage.class);
	
	public static final int BLACK = 0x000000;
	public static final int WHITE = 0xFFFFFF;

	/*
	 * Note that the input matrix uses 0 == white, 1 == black, while the output
	 * matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
	 */

	/**
	 *
	 * @param input Byte Matrix
	 * @param width Image Width
	 * @param height Image Height
	 * @param margin QR Code Margin
     * @return Bit Matrix
     */
	public static BitMatrix resultDecodec(ByteMatrix input, int width, int height, int margin) {
		if (input == null) {
			throw new IllegalStateException();
		}
		int inputWidth = input.getWidth();
		int inputHeight = input.getHeight();
		log.debug("Matrix Size:" + inputWidth + "*" + inputHeight);
		int qrWidth = inputWidth + (margin * 2);
		int qrHeight = inputHeight + (margin * 2);
		int outputWidth = Math.max(width, qrWidth);
		int outputHeight = Math.max(height, qrHeight);
		log.debug("Output Size:" + outputWidth + "*" + outputHeight);
		int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
		log.debug("Multiple:" + multiple);
		int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
		int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
		log.debug("Top Padding:" + topPadding);
		log.debug("Left Padding:" + leftPadding);
		BitMatrix output = new BitMatrix(outputWidth, outputHeight);

		for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
			for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
				if (input.get(inputX, inputY) == 1) {
					output.setRegion(outputX, outputY, multiple, multiple);
				}
			}
		}

		return output;
	}

	/**
	 *
	 * @param matrix Bit Matrix
	 * @param bgColor Background Color
	 * @param fgColor Code Color
     * @return Image Object
     */
	public static BufferedImage toBufferedImage(BitMatrix matrix, int bgColor, int fgColor) {
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height,
				(fgColor == BLACK && bgColor == WHITE) ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, matrix.get(x, y) ? fgColor : bgColor);
			}
		}
		return image;
	}
}
